#include "vit_wtvb02.hpp"

#ifndef VIT_WTVB02_USE_CONFIG_H
#define VIT_WTVB02_NAME  ("vit_wtvb02")

#define VIT_WTVB02_RS485_PATH  ("/dev/ttyUSB0")
#define VIT_WTVB02_RS485_BAUDRATE  (230400)
#define VIT_WTVB02_RS485_DE_PATH   ("/dev/gpiochip3")
#define VIT_WTVB02_RS485_DE_PIN  (24)
#define VIT_WTVB02_RS485_FRAME_TIMEOUT_MS  (100)

#define VIT_WTVB02_MODBUS_SLAVE_ADDR (0x50)
#endif // !VIT_WTVB02_USE_CONFIG_H



uart_v2 *Pvit_wtvb02_uart = NULL;
rs485_v3 *Pvit_wtvb02_rs485 = NULL;
agile_modbus_rtu_master_simple *Pvit_wtvb02_rtu_master = NULL;

static yj_return init_flag = YJ_ERROR;

int vit_wtvb02_rs485_modbus_read(uint8_t *data)
{
    if (!Pvit_wtvb02_rs485 || !Pvit_wtvb02_rtu_master || !Pvit_wtvb02_uart || !data)
        return -1;
    return Pvit_wtvb02_rs485->rs485_recv(data, MAX_ADU_LENGTH);
}

int vit_wtvb02_rs485_modbus_write(uint8_t *data, uint32_t len)
{
    if (!Pvit_wtvb02_rs485 || !Pvit_wtvb02_rtu_master || !Pvit_wtvb02_uart || !data)
        return -1;
    return Pvit_wtvb02_rs485->rs485_send(data, len);
}

yj_return vit_wtvb02_init(void)
{
    std::string name(VIT_WTVB02_NAME);
    Pvit_wtvb02_uart = new uart_v2(VIT_WTVB02_RS485_PATH, VIT_WTVB02_RS485_BAUDRATE, 8, 1,0.2);
    // Pvit_wtvb02_rs485 = new rs485_v3(Pvit_wtvb02_uart, VIT_WTVB02_RS485_DE_PATH, VIT_WTVB02_RS485_DE_PIN, VIT_WTVB02_RS485_FRAME_TIMEOUT_MS);
    Pvit_wtvb02_rs485 = new rs485_v3(Pvit_wtvb02_uart,  VIT_WTVB02_RS485_FRAME_TIMEOUT_MS);

    Pvit_wtvb02_rtu_master = new agile_modbus_rtu_master_simple(name,
                                                       vit_wtvb02_rs485_modbus_write,
                                                       vit_wtvb02_rs485_modbus_read);

    if (Pvit_wtvb02_rs485->rs485_open() != YJ_OK)
        return init_flag;
    if (Pvit_wtvb02_rtu_master->init() != 0)
        return init_flag;
    init_flag = YJ_OK;
    return init_flag;
}

void vit_wtvb02_deinit(void)
{
    if (Pvit_wtvb02_rs485)
    {
        Pvit_wtvb02_rs485->rs485_close();
        delete Pvit_wtvb02_rs485;
        Pvit_wtvb02_rs485 = NULL;
    }
    if (Pvit_wtvb02_rtu_master)
    {
        delete Pvit_wtvb02_rtu_master;
        Pvit_wtvb02_rtu_master = NULL;
    }
    if (Pvit_wtvb02_uart)
    {
        delete Pvit_wtvb02_uart;
        Pvit_wtvb02_uart = NULL;
    }
}

yj_return vit_wtvb02_read_all(vit_wtvb02_data_t *data)
{
    std::vector<uint16_t> dataTorecv(19);

    if (init_flag == YJ_ERROR || !data)
    {
        LOG(ERROR) << "❌ vit_wtvb02_read_all init_flag error or data is null";

        return YJ_ERROR;
    }
        
        if(Pvit_wtvb02_rtu_master->read_holding_register_multiple(VIT_WTVB02_MODBUS_SLAVE_ADDR,52,dataTorecv) < 0)
        {
            LOG(ERROR) << "❌ vit_wtvb02_read_all read holding regs error";
            return YJ_ERROR;
        }

        data->X_accel = (short)dataTorecv[0]*16*9.8/32768;// m/s^2
        data->Y_accel = (short)dataTorecv[1]*16*9.8/32768;// m/s^2
        data->Z_accel = (short)dataTorecv[2]*16*9.8/32768;// m/s^2
        data->X_vib_vel = (short)dataTorecv[6];//mm/s
        data->Y_vib_vel = (short)dataTorecv[7];//mm/s
        data->Z_vib_vel = (short)dataTorecv[8];//mm/s
        data->X_vib_shift = (short)dataTorecv[13];//um
        data->Y_vib_shift = (short)dataTorecv[14];//um
        data->Z_vib_shift = (short)dataTorecv[15];//um
        data->X_vib_freq = (short)dataTorecv[16]/10;//Hz
        data->Y_vib_freq = (short)dataTorecv[17]/10;//Hz
        data->Z_vib_freq = (short)dataTorecv[18]/10;//Hz
       
        data->temperature = (short)dataTorecv[12]/100.0;    //°c

    return YJ_OK;

}

void vit_wtvb02_print_data(vit_wtvb02_data_t *data)
{
    if (!data)
    {
       LOG(ERROR) << "vit_wtvb02_print_data data is null";
       return;
    }
    
    LOG(INFO) << "\n============= data start =============\n" 
    << "X_accel: " << data->X_accel << "m/s^2 " << "Y_accel: "<< data->Y_accel << "m/s^2 " << "Z_accel: " << data->Z_accel << "m/s^2\n"
    << "X_vib_vel: " << data->X_vib_vel << "mm/s " << "Y_vib_vel: " << data->Y_vib_vel << "mm/s " << "Z_vib_vel: " << data->Z_vib_vel << "mm/s\n"
    << "X_vib_shift: " << data->X_vib_shift << "um " << "Y_vib_shift: " << data->Y_vib_shift << "um " << "Z_vib_shift: " << data->Z_vib_shift << "um\n"
    << "X_vib_freq: " << data->X_vib_freq << "Hz " << "Y_vib_freq: " << data->Y_vib_freq << "Hz " << "Z_vib_freq: " << data->Z_vib_freq << "Hz\n"
    << "temperature: " << data->temperature << "°C \n" 
    << "============= data end =============\n";
}